package model;

import org.jbox2d.common.Vec2;
import org.newdawn.slick.Image;
import behaviors.Behavior;
import controller.Global;

/**
 * Definition file for all objects in the game world defined in the loosest
 * possible way in order to capture various needs not met by JBox2D's built-in
 * world/body iterator.
 * 
 * @author Jonathan Schultz
 * @version %I%, %G%
 * @since 1.0
 */
public class Entity extends MetaBody {

	public Entity() {
		setDefault();
	}

	// register behavior by name using reflection
	public void register(String className) {
		Class<?> cls = null;
		Object object = null;
		
		try {
			cls = Class.forName(className);
		} catch (ClassNotFoundException e1) {
			e1.printStackTrace();
		}
		try {
			object = cls.newInstance();
			behaviorList.add((Behavior) object);
		} catch (InstantiationException e1) {
			e1.printStackTrace();
		} catch (IllegalAccessException e1) {
			e1.printStackTrace();
		}
	}

	// unregister behavior
	public void unregister(String className) {
		Class<?> cls = null;
		Object object = null;
		
		try {
			cls = Class.forName(className);
		} catch (ClassNotFoundException e1) {
			e1.printStackTrace();
		}
		try {
			object = cls.newInstance();
			behaviorList.remove((Behavior) object);
		} catch (InstantiationException e1) {
			e1.printStackTrace();
		} catch (IllegalAccessException e1) {
			e1.printStackTrace();
		}
	}

	public void render() {
		Vec2 pos = null;
		float sx, sy;
		Image image;

		if (type != COMPOUND) {

			if (Global.player != null
					&& Math.abs(x - Global.player.getPosition().x) <= Global.metersX) {

				pos = Global.worldToScreen(x, y);

				// adjust image center
				if (type == Entity.CIRCLE) {
					pos.x -= Global.pixelsPerMeter * radius;
					pos.y -= Global.pixelsPerMeter * radius;
				} else if (type == Entity.POLYGON) {
					pos.x -= Global.pixelsPerMeter * sizeX;
					pos.y -= Global.pixelsPerMeter * sizeY;
				}

				// draw image
				if (this.image != null) {

					if (type == Entity.CIRCLE) {
						sx = sy = radius * (Global.pixelsPerMeter * 2f);
					} else {
						sx = sizeX * (Global.pixelsPerMeter * 2f);
						sy = sizeY * (Global.pixelsPerMeter * 2f);
					}

					image = this.image.getFlippedCopy(facing, false);

					if (type == Entity.CIRCLE) {
						image.setCenterOfRotation(Global.pixelsPerMeter
								* radius, Global.pixelsPerMeter * radius);
					} else {
						image.setCenterOfRotation(
								Global.pixelsPerMeter * sizeX,
								Global.pixelsPerMeter * sizeY);
					}

					// if entity has a body that can rotate, rotate it
					if (body != null) {
						image.setRotation((float) -Math.toDegrees(body
								.getAngle()));
					}
					image.draw(pos.x, pos.y, sx, sy);
				}
			}
		} else {
			for (Entity e : entityList) {
				e.render();
			}
		}
	}

	public void update() {
		long time = System.currentTimeMillis();

		if (timeToDie != -1 && time > timeToDie) {
			recycle = true;
		}
		if (recycle) {
			if (!body.isStatic() && !body.isBullet()) {
				Stage.buoyancy.removeBody(body);
			}
			Global.world.destroyBody(body);
			return;
		}
		for (Behavior b : behaviorList) {
			b.update(body);
		}
	}
}
